using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace cframework.lockstep
{ 
    public class MsgQueue<T>
    {
        T[] frameMsgArr;

        int writeIndex = 0;
        int readIndex = 0;
        int capility = 0;

        public MsgQueue(int _capility)
        {
            capility = _capility;
            frameMsgArr = new T[capility];
        }

        public int Capility
        {
            get
            {
                return capility;
            }
        }

        public int Length()
        {
            int len = (writeIndex + frameMsgArr.Length - readIndex) % frameMsgArr.Length;
            if (len == 0)
            {
                if (CanDequeue())
                {
                    return frameMsgArr.Length;
                }
            }

            return len;
        }

        public void Reset()
        {
            System.Array.Clear(frameMsgArr, 0, frameMsgArr.Length);
            writeIndex = 0;
            readIndex = 0;
        }

        public bool CanEnqueue()
        {
            return EqualityComparer<T>.Default.Equals(frameMsgArr[writeIndex], default(T));
        }


        public bool Enqueue(T data)
        {
            if (data == null)
            {
                return false;
            }

            if (!CanEnqueue())
            {
                return false;
            }

            frameMsgArr[writeIndex] = data;
            writeIndex = (writeIndex + 1) % frameMsgArr.Length;
            return true;
        }

        public bool CanDequeue()
        {
            return !EqualityComparer<T>.Default.Equals(frameMsgArr[readIndex], default(T));
        }

        public T Dequeue()
        {
            if (!CanDequeue())
            {
                return default(T);
            }

            var data = frameMsgArr[readIndex];
            frameMsgArr[readIndex] = default(T);
            readIndex = (readIndex + 1) % frameMsgArr.Length;

            return data;
        }
    }
}